#include <iostream>
#include <string>


#include <save-traces.h>
#include <osa-control.h>
#include <esp301-control.h>
#include "options.h"

const char beep='\a';

const unsigned trace_length=1001;
unsigned wavelength_start=1070;
unsigned wavelength_stop=1100;
float bw_res = 0.5;
float ref_level = -40;
float sensitivity = -60;

bool batch_scan = 0;
unsigned number_of_scan=1;
double beginning_displacement=0;
double line_height=0;

std::string title = "";

void printParams()
{
  std::cout << "title = '" << title << '\'' << std::endl
			<< "trace length = " << trace_length << std::endl
            << "wavelength start = " << wavelength_start << std::endl
            << "wavelength stop = " << wavelength_stop << std::endl
            << "resolution bandwidth = " << bw_res << std::endl
            << "reference_level = " << ref_level << std::endl
            << "sensitivity = " << sensitivity << std::endl;
if(number_of_scan !=1)
  std::cout << "number_of_scan = " << number_of_scan << std::endl
            << "line_height = " << line_height << std::endl;
}

void interactive_record(esp301_control &Motion_controller,osa_control &Agilent_OSA,save_traces &data)
{
  std::string command;
  unsigned count=0;
  while (1)
    {
      std::cout << "Type 'c' to capture one trace, 'q' to save and quit: " << beep;
      std::getline(std::cin,command);

      if (command.length() != 1 )
        {
          std::cout << "Wrong command. (Did you turn off the Caps Lock?)" << std::endl;
          continue;
        }

      if (command == "q") break;
      else if (command == "c")
        {
      float current_displacement = Motion_controller.getPosition();
      std::cout << "Current position: " << current_displacement << std::endl;

          std::cout << "Capturing trace #" << (++count) << "..." << std::endl;

          float y[trace_length];
          Agilent_OSA.get_trace(y,trace_length);

          data.input_trace(current_displacement,y,trace_length);
        }
      else
        {
          std::cout << "Wrong Command." << std::endl;
          continue;
        }
    }

}

void batch_record(esp301_control &Motion_controller, osa_control &Agilent_OSA,save_traces &data,double beginning_displacement,unsigned number_of_scans, double line_height)
{
//Motion_controller.calibrate();
Motion_controller.moveTo(beginning_displacement);

  for (unsigned count=1; count<=number_of_scans; count++)
    {
      float current_displacement = Motion_controller.getPosition();

      std::cout << "Capturing trace #" << count << " at position=" << current_displacement << '\r' << std::flush;
      float y[trace_length];
      Agilent_OSA.get_trace(y,trace_length);
      data.input_trace(current_displacement,y,trace_length);

      Motion_controller.moveBy(line_height);
    }
  std::cout << std::endl;
}

int	main(int argc, char *argv[])
{
Poco::Data::SQLite::Connector::registerConnector();

  try
    {
// parse parameters and change default values
      bool success = parseOptions(argc, argv,
                                  //&trace_length,
 &wavelength_start, &wavelength_stop, &bw_res, &ref_level, &sensitivity,
&batch_scan,&beginning_displacement,&number_of_scan,&line_height,
&title);


      if (! success) return 1;

      printParams();
    }
  catch (char const* e)
    {
      std::cerr << "Error: " << e << std::endl;
      return 1;
    }

  try
    {
      //std::string filename="TR";

      save_traces data(trace_length,wavelength_start,wavelength_stop,sensitivity,bw_res,title);

      std::cout << "Connecting to device..." << std::endl;
      esp301_control Motion_controller;
      osa_control Agilent_OSA("10.42.43.100","hpib7,1");

      std::cout << "Preset device..." << std::endl;
      Agilent_OSA.initialize(wavelength_start,wavelength_stop,sensitivity,ref_level,bw_res,trace_length);

      std::cout << "Start acquisition..." << std::endl;

      if (!batch_scan)
      {
        std::cout << "***Interactive mode" << std::endl;
        interactive_record(Motion_controller,Agilent_OSA,data);
      }
      else
      {
        std::cout << "**Batch mode" << std::endl;
        batch_record(Motion_controller,Agilent_OSA,data,beginning_displacement,number_of_scan,line_height);
      }

/*
// Save to file
      std::cout << "Saving data..." << std::endl;

        data.write_to_file();
*/
    }
  catch (const char* err_msg)
    {
      std::cerr <<"Caught exception: " << err_msg << std::endl;
      return 1;
    }
  catch (std::string err_msg)
    {
      std::cerr <<"Caught exception: " << err_msg << std::endl;
      return 1;
    }
Poco::Data::SQLite::Connector::unregisterConnector();
  std::cout << "End of acquisition." << std::endl;
  return 0;
}
